NOTE: This Technical Q&A has been retired. Please see the Technical Q&As page for current documentation.

Technical Q&A NW11
Obtaining a List of Volumes from a Server Programmatically


Q: How do I obtain a list of volumes from a server programmatically, given that I have the atalk-internet address of that server?

A: To obtain a list of volumes from a server programatically, you use an AFPCommand called afpGetSParms. This command requires you to log in (as either a guest or a user) and create a session, and then issue the afpGetSParms. The string returned by afpGetSParms, which is described on page 13-98 of Inside AppleTalk,looks like this:

[0-3]   long    Current Date-time on Server's clock
[4] byte    Number of Volumes that follow
---->    byte    NumVol Structure...
        Msb = HasPassword (bit)
        Lsb = HasConfigInfo (appleII stuff, ignore it)
    P-String    Volume Name
<----

The string is repeated for each volume.

There is also an example in the February 1995 Developer CD:

Dev.CD Feb 95:Sample Code:Snippets:Networking:AppleTalk Libraries

The string from this example looks like this:

short LogOnAsGuest(AddrBlock *serverAddress,Ptr SCBBlock)
  {
    AFPLoginPrm *XPPBlock;  /* to build parameter blocks for AFP */
    short       cbsize;
    char        XPPReply[quantumSize*8];
         /* used to get AFP replies (max. size 8 ATP packet) */
    char        XPPCmd[quantumSize]; /* used to send AFP commands */
    OSErr       error;
    short       result;
-   /* information used by Login function */
    char        AFPVersion[30];
    char        AuthentMethod[30];

    strcpy(AFPVersion, "AFPVersion 2.0");
    strcpy(AuthentMethod, "No User Authent");

    if (!(XPPBlock = (AFPLoginPrm *)NewPtrClear(sizeof(AFPLoginPrm))))
        return MemError();

    XPPBlock->ioRefNum = xppRefNum;
    XPPBlock->ioCompletion = nil;
    XPPBlock->aspTimeout = 1;    /* Timeout for ATP */
    XPPBlock->aspRetry = 2;      /* Retry count for ATP */
    XPPBlock->afpAddrBlock = *serverAddress;
           /* AppleTalk address of the server */
    XPPBlock->afpAttnRoutine = nil ;
    XPPBlock->rbPtr = (Ptr)XPPReply; /* Reply buffer pointer */
    XPPBlock->rbSize = quantumSize;  /* Reply buffer size */

    /* prepare command information :
       1st byte : command (login)
       2nd Pascal string : AFP version
       3rd Pascal string : Authentication
                           Method - see Inside AppleTalk 13-104 */
    XPPCmd[0] = afpLogin;
    XPPCmd[1] = strlen(AFPVersion);
    strcpy(XPPCmd+2,AFPVersion);
    cbsize = strlen(XPPCmd);
    XPPCmd[cbsize] = strlen(AuthentMethod);
    strcpy(XPPCmd+cbsize+1,AuthentMethod);
    cbsize = strlen(XPPCmd);

    XPPBlock->cbPtr = (Ptr)XPPCmd; /* Command block pointer */
    XPPBlock->cbSize = cbsize;
    XPPBlock->afpSCBPtr = (Ptr) SCBBlock; /* SCB pointer in AFP login */
    if ((error = AFPCommand((XPPParmBlkPtr)XPPBlock,sync)) != noErr)
        result = error;
    else
        if (XPPBlock->cmdResult != noErr)
           result =  XPPBlock->cmdResult ;
        else result =  XPPBlock->sessRefnum;
                /* return session number */

    DisposPtr((Ptr)XPPBlock);
    return result;
}   /* LogOnAsGuest */
OSErr GetServerParams(short sessNum,Ptr replyBuffer,short buffLength)
{
    XPPPrmBlk   *XPPBlock; /* to build parameter blocks for AFP */
    char        XPPCmd[quantumSize];/* used to send AFP commands */
    OSErr       error;

    if (!(XPPBlock = (XPPPrmBlk *)NewPtrClear(sizeof(XPPPrmBlk))))
        return MemError();
    XPPBlock->ioRefNum = xppRefNum; /* driver reference number */
    /* prepare command information :
        no input provided except command - see IA 13-98 */
    XPPCmd[0]  = afpGetSParms;

    XPPBlock->sessRefnum = sessNum;
    XPPBlock->aspTimeout = 2; /* Timeout for ATP */
    XPPBlock->aspRetry = 2;
    XPPBlock->cbPtr = (Ptr)XPPCmd;
    XPPBlock->cbSize = 1;            /* Command block size */
    XPPBlock->rbPtr = replyBuffer;   /* Reply buffer pointer */
    XPPBlock->rbSize = buffLength;
    XPPBlock->wdSize = 0;    /* Write Data size */
    XPPBlock->wdPtr = nil;      /* Write Data pointer */

    error = AFPCommand((XPPParmBlkPtr)XPPBlock,sync);
    DisposPtr((Ptr)XPPBlock);
    return error;
 }
main()
{
Str32 theServer;
Ptr buffer;
AddrBlock serverAddress;
char SCBBlock[scbMemSize]; /* used by AFP to manage a session */
short sessionNum;
OSErr ErrNo;
short refNum;
/* allocate a buffer to retrieve info */
    if (!(buffer = NewPtr(buffSize))) return;

/* open .XPP driver */
    ErrNo = OpenXPP(&refNum);
// hard coded address cause I'm lazy
    serverAddress.aNet = 41107;
    serverAddress.aNode = 87;
    serverAddress.aSocket = 250;

// simple login as guest
    if ((sessionNum = LogOnAsGuest(
             &serverAddress,&SCBBlock)) <= 0) {
        DisposePtr(buffer);
        return;
        }
// get server params
    if ((ErrNo = GetServerParams(sessionNum,
                buffer,buffSize)) != noErr) {
        DisposePtr(buffer);
        return;
        }
// buffer has server string

// be a good citizen
    LogOut(sessionNum,&SCBBlock);
    DisposePtr(buffer);
}

[June 01 1995]


Developer Documentation | Technical Notes | Development Kits | Sample Code